package org.example;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.wechat_qrcode.WeChatQRCode;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.net.URL;
import java.util.List;
public class WeChatQRCodeTool {

    private static volatile  WeChatQRCodeTool instance;
    private static volatile WeChatQRCode detector;

    private WeChatQRCodeTool(){
        System.setProperty("java.awt.headless","true");
        URL url = null;
        String os = System.getProperty("os.name");
        if(os.startsWith("Linux")){
            url = ClassLoader.getSystemResource("opencvlib/libopencv_java453.so");
        }else{
            url = ClassLoader.getSystemResource("opencvlib/opencv_java453.dll");

        }
        System.load(url.getPath());
        detector = new org.opencv.wechat_qrcode.WeChatQRCode();
    }

    public static WeChatQRCodeTool getInstance(){
        if(instance==null){
            synchronized (WeChatQRCodeTool.class){
                if(instance==null){
                    instance = new WeChatQRCodeTool();
                }
            }
        }
        return instance;
    }

    public static Mat bufImg2Mat(BufferedImage original, int imgType, int matType) {
        if (original == null) {
            throw new IllegalArgumentException("original == null");
        }
        byte[] pixels = null;
        // Don't convert if it already has correct type
        if (original.getType() != imgType) {

            // Create a buffered image
            BufferedImage image = new BufferedImage(original.getWidth(), original.getHeight(), imgType);

            // Draw the image onto the new buffer
            Graphics2D g = image.createGraphics();
            try {
                g.setComposite(AlphaComposite.Src);
                g.drawImage(original, 0, 0, null);
                pixels = ((DataBufferByte)image.getRaster().getDataBuffer()).getData();
            } finally {
                g.dispose();
            }
        } else {
            pixels = ((DataBufferByte) original.getRaster().getDataBuffer()).getData();
        }
        Mat mat = Mat.eye(original.getHeight(), original.getWidth(), matType);
        mat.put(0, 0, pixels);
        return mat;
    }

    public String decode(BufferedImage srcImage) {
        int cvtype = CvType.CV_8UC3;
        if(srcImage.getType() == BufferedImage.TYPE_BYTE_GRAY) {
            cvtype = CvType.CV_8UC1;
        }
        Mat image = bufImg2Mat(srcImage, srcImage.getType(), cvtype);
        List<String> result2 = detector.detectAndDecode(image);
        if (result2 != null && result2.size() > 0) {
            return result2.get(0);
        }
        return null;
    }

    public String decodeQRCodeByPath(String qrCodePath){
        String qrCodeText = null;
        try {
            BufferedImage image = ImageIO.read(new File(qrCodePath));
            qrCodeText = decode(image);
        }catch (Exception e){
            e.printStackTrace();
        }
        return qrCodeText;
    }


    public static void main(String[] args) {
        String img = "C:\\Users\\86159\\Pictures\\qr-3.jpg";
        String result = getInstance().decodeQRCodeByPath(img);
        System.out.println(result);
    }
}